-- UICartoon
-- Created by zouyb
-- 漫画显示界面

-- 状态
CARTOON_STATUS_INIT      =  0;
CARTOON_STATUS_PLAYING   =  1;
CARTOON_STATUS_FINISH    =  2;
CARTOON_STATUS_EXIT      =  3;

UICartoon = class("UICartoon", function()
    return cc.Layer:create();
end);

function UICartoon.create(cartoonId, callback)
    return UICartoon.new(cartoonId, callback);
end

-- 构造函数
function UICartoon:ctor(cartoonId, callback)
    self:setName("UICartoon");
    local node = cc.CSLoader:createNode("layout/cartoon/Cartoon.csb");
    self:addChild(node);
    self.node = node;

    self.cartoonId = cartoonId;
    self.callback = callback;

    local zOrder = UIMgr.TOP_MENU_ZORDER + 100000;
    self:setLocalZOrder(zOrder);

    self:resize();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 初始状态
    self.status = CARTOON_STATUS_INIT;

    --  渐显特效
    self.mask:setOpacity(0);
    local fadeIn = cc.FadeIn:create(1.5);
    local callFunc = cc.CallFunc:create(function()
            self:play(self.cartoonId);
    end);
    self.mask:runAction(cc.Sequence:create(fadeIn, callFunc));
end

-- 适配
function UICartoon:resize()
    local width = AlignM.frameSize.width;
    local height = AlignM.frameSize.height;

    local node = self.node;

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    self.mask = findChildByName(self.node, "mask");
    self.mask:setPosition(width/2, height/2);
    self.mask:setContentSize(width, height);
end

-- 注册点击事件
function UICartoon:registerTouchEvent()
    -- 点击处理
    local function onClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            if self.status == CARTOON_STATUS_PLAYING then
				-- 正在播放，不允许跳过
            elseif self.status == CARTOON_STATUS_FINISH then
                self.status = CARTOON_STATUS_EXIT;

                -- 显示下一个漫画
                local nextCartoonId = CartoonM.query(self.curCartoonId, "next");
                if nextCartoonId > 0 then
                    self:play(nextCartoonId);
                else
                    --  渐隐特效
                    local parent = findChildByName(self.node, "CT/effect_node");
                    parent:removeAllChildren();
                    self.mask:setOpacity(255);
                    local fadeOut = cc.FadeOut:create(2);
                    local callFunc = cc.CallFunc:create(function()
                        -- 调用回调函数
                        if self.callback then
                            self.callback();
                        end
                        UIMgr.getCurrentScene():removeFormByName("UICartoon");
                    end);
                    self.mask:runAction(cc.Sequence:create(fadeOut, callFunc));
                end
            end
        end
    end

        self.mask:addTouchEventListener(onClick);
end

-- 播放效果
function UICartoon:play(cartoonId)
    local width = AlignM.frameSize.width;
    local height = AlignM.frameSize.height;

    -- 保存当前漫画ID
    self.curCartoonId = cartoonId;

    local parent = findChildByName(self.node, "CT/effect_node");
    parent:stopAllActions();
    parent:removeAllChildren();
    parent.cartoonEffectNode = nil;

    -- 播放背景音乐
    local bgm = CartoonM.query(cartoonId, "bgm");
    print("cartoon bgm:"..tostring(bgm));
    AudioM.playBgMusic(bgm);

    -- 适配策略，铺满屏幕
    local function resize(node)
        local scale1 = math.min(width / DESIGN_WIDTH, height / DESIGN_HEIGHT);
        local scale2 = math.min(width / 640, height / 1136);

        node:setScaleX(scale2 / scale1);
        node:setScaleY(scale2 / scale1);
    end

    -- 中间加个父节点，用来做适配
    if parent.cartoonEffectNode == nil then
                parent.cartoonEffectNode = cc.Node:create();
                parent:addChild(parent.cartoonEffectNode);

                -- 适配
                resize(parent.cartoonEffectNode);
    end

        local effect;

    -- 特效ID
    local effectId = CartoonM.query(cartoonId, "effect_id");
    local endFrameId = CartoonM.query(cartoonId, "end_frame_id");

    -- 帧回调
    local function frameEventCallback(frame)
        if frame.getEvent and frame:getEvent() == "pilor" then
            local index = frame:getFrameIndex();

            -- print("frame index" .. index);

            if index == endFrameId then
                                self.status = CARTOON_STATUS_FINISH;
            end

            -- 从某帧开始播放文字动画
            if self.textStartFrameIndex and self.textStartFrameIndex[index] then
                for _, i in ipairs(self.textStartFrameIndex[index]) do
                    self:playTextEffect(i);
                end
            end
        end
    end

    -- 播放动画
    _, effect = playEffect(parent.cartoonEffectNode, effectId, 0, 0, frameEventCallback);
        self.effect = effect;

    -- 获取动画中待补充节点
    local iconList = CartoonM.query(cartoonId, "icon_list");
    local iconNodeList = {};
    -- 添加底框
    for i = 1, #iconList do
        local id = iconList[i];
        local nodeName = CartoonM.queryBubbleInfo(id, "node_name");
        print ("nodeName:" .. nodeName);
        local node = findChildByName(effect, nodeName.."/SpriteObject");
        if node then
            table.insert(iconNodeList, node);
        end
    end

    for i = 1, #iconList do
        local id = iconList[i];
        local node = iconNodeList[i];
        local iconPath = getCartoonIconPath(CartoonM.queryBubbleInfo(id, "icon"));
        local imageView = ccui.ImageView:create();
        imageView:loadTexture(iconPath);
        node:addChild(imageView);

        -- 根据不同语言版本可以适当对泡框做不同的横向拉伸
        -- TODO
        imageView:setScaleX(1.1);
    end

    -- 添加文字
    local textList = CartoonM.query(cartoonId, "text_list");
    local nodeList = {};
    self.textNodeList = {};
    self.textLettersList = {};
    self.textStartFrameIndex = {};
    for i = 1, #textList do
        local textId = textList[i];
		local nodeName = CartoonM.queryTextInfo(textId, "node_name");
        local node = findChildByName(effect, nodeName.."/SpriteObject");
        if node then
            table.insert(nodeList, node);
        end
    end

    for i = 1, #textList do
        local textId = textList[i];
        local node = nodeList[i];

        local textNode = TextPoolM.createTextObject(TextStyleM.TEXT_SIZE_TINY);
        local kerning = 0;
        if not isFullWidthLang() then
            kerning = -1;
        end
        TextStyleM.setTextStyle(textNode,TextStyleM.TEXT_SIZE_TINY, TextStyleM.TEXT_COLOR_DARK_BROWN, false, kerning);
        local text = CartoonM.queryTextInfo(textId, "talk");
        textNode:setString(text);
        textNode:setTextHorizontalAlignment(cc.TEXT_ALIGNMENT_CENTER);
        if cartoonId == 3 then
            textNode:setPositionY(textNode:getPositionY() - 4);
        end
        node:addChild(textNode);
        self.textNodeList[i] = textNode;

        -- 是否有出字效果
        if CartoonM.queryTextInfo(textId, "text_effect") == 1 then
            local startTextFrameId = CartoonM.queryTextInfo(textId, "start_text_frame_id");
            if self.textStartFrameIndex[startTextFrameId] == nil then
                self.textStartFrameIndex[startTextFrameId] = {};
            end

            table.insert(self.textStartFrameIndex[startTextFrameId], i);

            self:collectLetters(i, text);
        end
    end

    -- 添加特效
    local effectList = CartoonM.query(cartoonId, "effect_list");
    local effectNodeList = {};

    for i = 1, #effectList do
        local id = effectList[i];
        local nodeName = CartoonM.queryEffectInfo(id, "node_name");
        local node = findChildByName(effect, nodeName);
        if node then
            print("node:" .. nodeName);
            table.insert(effectNodeList, node);
        end
    end

    for i = 1, #effectList do
        local id = effectList[i];
        local effectId = CartoonM.queryEffectInfo(id, "effect_id");

        local node = effectNodeList[i];

        print("playEffect:" .. effectId);
        playEffect(node, effectId, 0, 0);
    end

	self.status = CARTOON_STATUS_PLAYING;
end

-- 收集字符列表
function UICartoon:collectLetters(index, text)
    local textLabel = self.textNodeList[index];
    local count = string.getWCharCount(text);
    local letters = {};

    local i = 0;
    local endPos = count - 1;
    local charPos = 0;
    local curPaddingCount = 0;
    local lineNum = 0;
    while i <= endPos do
        local letter = textLabel:getVirtualRenderer():getLetter(i);
        local nextLetter = textLabel:getVirtualRenderer():getLetter(i+1);
        if letter then
            -- 初始所有字符置为不可见
            letter:setOpacity(0);
            letter.lineNum = lineNum;

            -- 加入到字符列表
            table.insert(letters, 1, letter);
        else
            if nextLetter ~= nil then
                lineNum = lineNum + 1;

                if not string.isBreakLineChar(text, charPos-curPaddingCount) then
                    -- 如果是系统自动添加的换行符，需要把结束位置往后挪
                    endPos = endPos + 1;
                    curPaddingCount = curPaddingCount + 1;
                end
            end
        end

        i = i + 1;
        charPos = charPos + 1;
    end

    self.textLettersList[index] = letters;
end

-- 对话效果，一个字一个字慢慢播放
function UICartoon:playTextEffect(index)
    local function play()
        local letters = self.textLettersList[index];
        local textLabel = self.textNodeList[index];

        local duration = 0.1;
        if getLang() ~= "zh" and getLang() ~= "tw" then
            duration = 0.05;
        end

        if #letters > 0 then
            local letter = letters[#letters];
            table.remove(letters, #letters);
            local fadeIn = cc.FadeIn:create(duration);
            local callFunc = cc.CallFunc:create(function()
                if 0 == #letters then
                    print("finished");
                    -- 标记字体播放完成
                    self.isFinished = true;
                end
            end);

            self.isFinished = false;
            letter:runAction(cc.Sequence:create(fadeIn, callFunc));
            performWithDelay(textLabel, play, duration);
        end
    end

    play();
end



